Contexto

Vimos, em nota anterior, como fabricar mapas estáticos usando o pacote ggplot2. O objetivo, agora, era criar mapas interativos em aplicativos shiny.

Felizmente, uma solução fantástica, recentemente criada, já está dispinível no CRAN. Trata-se do pacote leflet.

O pacote utiliza o Leaflet, uma solução opensource em JavaScript que permite melhor interação com mapas

Sobre este tutorial

Um tutorial bastante completo sobre o leaflet-R está disponível aqui. Este tutorial foi contruído com o intuido de mostrar a funcionalidade, e para fins de registro pessoal, também.

Os dados para exemplificar a construção dos mapas seguem neste link. Mas, não se preocupe em baixar manualmente. Ao longo da exposição, haverá códigos que reaizarão esse trabalho.

Os exemplos vão ser expostos para que você possa reproduzí-los passo-a-passo e ver as camadas sendo acrescentadas. No entanto, apenas o resultado final, com um ou outro intermediários, serão mostrados aqui.

Variáveis globais e pacotes

Vamos utilizar os pacotes que estão sendo carregados abaixo. Caso não tenha a última versão destes, descomente a linha final do chunck abaixo e execute a linha de comando.

library(rgdal)   # para carregar o shape
library(leaflet) # é o tema do artigo...
library(dplyr)   # para usar o operador "%>%"

Obtenção e leitura dos dados

Os dados utilizados são arquivos .shp dos municípios da região sudeste. Vamos construir mapas interativos com informações de população e analfabetismo. Mas existem outras variáveis para brincar, também…

No código abaixo, vamos fazer o download do shape e descompactar os arquivos

# objeto 'link_download' guarda o endereço dos dados que vamos usar
link_download <- "https://gitlab.com/Wjsilva/exemplos_r/raw/previa/dados/c10_sudeste.zip"

# criando arquivo e diretórios temporários
tf <- tempfile()
td <- tempdir()

# baixando e descompactando
download.file(link_download,destfile = tf)
unzip(tf,exdir = td)

Agora, vamos carregar o shape usando a função rgdal::readOGR. Bastam os argumentos dsn, que é a nossa pasta td, temporária, e o nome do shape, sem o formato. Um plot é realizado apenas para checar se tá tudo certo. A opção encoding serve para organizar os caracteres especiais dos nome dos municípios.

c10_sudeste <- readOGR(dsn = td, layer = "c10_sudeste",encoding = "UTF-8")
## OGR data source with driver: ESRI Shapefile 
## Source: "C:\Users\WESLEY~1.JES\AppData\Local\Temp\RtmpkX0OZl", layer: "c10_sudeste"
## with 1668 features
## It has 51 fields
plot(c10_sudeste)

Pasos do leaflet R

O básico

O primeiro passo é chamar o lefalet e, opcionalmente, declarar a fonte de dados e outras opções, como largura e comprimento. Isso é feito usando a funçãoleaflet(data). No código abaixo, criamos um default. É possível deixar para inserir a fonte de dados posteriormente, em outras etapas. Aqui, vamos “declarar” os municípios do sudeste como fonte de dados. Os nossos municípios ainda não vão aparecer.

mapa <- leaflet(data = c10_sudeste)
mapa

Ao criar o objeto mapa, nada acontece, a não ser a criação deste elemento de classe leaflet, htmlwidget. Quando executamos esse objeto, aparece um “mapa” vazio, apenas com a opção de zoom.

Determinar basemap

O próximo passo, ou “camada”, é determinar um basemap usando a função addTiles. Jà existe um defaul pronto, que vai ser mostrado, e outro mais legal que será usado até o fim.

mapa %>% addTiles()

O comando acima equivale exatamente ao comando abaixo (afinal, essa é a funcionalidade do operador “%>%”).

addTiles(mapa)

Para ilustrar a flexibilidade de escolha do basemape, vamos utilizar um exemplo utilizado no próprio help da função leflet().

mapa <- leaflet(data = c10_sudeste) %>%
  addTiles('http://{s}.basemaps.cartocdn.com/dark_all/{z}/{x}/{y}.png',
           attribution = paste(
             '&copy; <a href="http://openstreetmap.org">OpenStreetMap</a> contributors',
             '&copy; <a href="http://cartodb.com/attributions">CartoDB</a>'
             )
           )
mapa

Adicionar polígonos não tematizados

A próxima camada envolve o “desenho” do polígono no basemap.

mapa %>% addPolygons()

com a opção weight podemos diminuir a expessura das linhas. Com fillColor mudamos a cor de preenchimento, e color muda a cor da linha. Vamos deixar com linhas vermelhas e preenchimento azul A transparência também pode (e será) modificada com fillOpacity = 0.9

mapa %>% addPolygons(weight = 1, fillColor = "Blue",
                                    color = "red",fillOpacity = 0.9)

Tematizar com base em uma variável

Para ilustrar, vamos fazer um mapa temático da população total (npes. Para fazer isso, são necessários dos passos.

  1. Criar uma espécie de função que criará uma escala de cores em função das classes de valores da variável
  2. “executar” essa função no meio da adição dos polígonos.
blues = colorNumeric("Blues", domain = c10_sudeste$npes)
mapa %>% addPolygons(weight = 0.1, fillColor = ~blues(npes),
                     color = "blue",fillOpacity = 0.9,
                     smoothFactor = 0.5)

## Obs: a opção "smoothFactor" tem a ver com o nível de distorção dos polígonos, causada pela simplificação, com o intuito de otimizar o processamento

Para outro exemplo, usando outro esquema de cores, vamos fazer o mesmo para a taxa de analfabetismo.

greens = colorNumeric("Greens", domain = c10_sudeste$tx_analfab)
mapa2 <- mapa %>% addPolygons(weight = 0.1, fillColor = ~greens(tx_analfab),
                             color = "green",fillOpacity = 0.9,
                             smoothFactor = 0.5)
mapa2

Adicionando legenda e pop-up

Outra opção essencial é a adição de legenda. Isso é feito na camada addLegend(). Repare que recriamos o objeto ‘mapa’ no objeto ‘mapa2’, que contém o mapa base e os polígonos tematizados.

A legenda será simplesmente acrescentada a esse objetos no atual status, e será mostrado no canto inferior direito (position = “bottromright”). Usamos a mesma palheta de cores (“função” greens) e a mesma variável (values = ~tx_analfab).

mapa3 <- mapa2 %>% addLegend(position = "bottomright", pal = greens,values = ~tx_analfab)
mapa3

Uma última opção interessante é acrescentar pop-ups nos polígonos. Isso é feito com base na camada addPopups. No nosso caso, vamos mostrar como pop-up o nome do município, seguido de um traço (" - “”) e o valor da taxa de analfabetismo. Por enquanto, só consegui adicionar essa opção ao inserir os polígonos (outra alternativa, pois a função addPolygons tem a opção popup).

Repare que aqui estou recriando tudo do zero. Essa é uma boa oportunidade para entender o leaflet como construção de elementos camada a camada. Essa funcionalidade, aliás, é bem semelhante à do ggplot2. Seria possível, por exemplo, acrescentar mais uma camada via addPolygons para acrescentar os limites de UF, por exemplo. Ou adicionar outro arquivo com dados pontuais ou de linhas.

## Warning in doColorRamp(colorMatrix, x, alpha, ifelse(is.na(na.color), "", :
## '.Random.seed' is not an integer vector but of type 'NULL', so ignored